package com.robertlancer.supershare.util;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.services.json.AbstractGoogleJsonClient;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.client.util.Maps;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.GmailScopes;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.security.*;
import java.security.cert.CertificateException;
import java.util.Collection;
import java.util.Map;
public class ServiceFactory {
public static String emailAddress;
public static PrivateKey privateKey;
static {
File privateKeysDirectory = new File("WEB-INF/privatekey/");
if (!privateKeysDirectory.exists()) {
throw new RuntimeException("You must have a privatekey directory underneath the WEB-INF directory.");
}
File[] filesUnderPrivateKey = privateKeysDirectory.listFiles();
if (filesUnderPrivateKey.length == 0)
throw new RuntimeException("You must have a private key underneath the WEB-INF/privatekey/ directory.");
try {
emailAddress = System.getProperty("serviceAccountEmailAddress");
InputStream iss = new FileInputStream(filesUnderPrivateKey[0]);
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(iss, "notasecret".toCharArray());
privateKey = (PrivateKey) keystore.getKey("privatekey", "notasecret".toCharArray());
} catch (UnrecoverableKeyException e) {
e.printStackTrace(System.err);
} catch (CertificateException e) {
e.printStackTrace(System.err);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace(System.err);
} catch (KeyStoreException e) {
e.printStackTrace(System.err);
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
public static Gmail getGmailService(String email) {
return (Gmail) getService_Singleton(email, Gmail.class);
}
public static Drive getDriveService(String email) {
return (Drive) getService_Singleton(email, Drive.class);
}
public static String getAccessToken(AbstractGoogleJsonClient jsonClient) {
GoogleCredential googleCredential = ((Intializer) jsonClient.getRequestFactory().getInitializer()).credential;
if (googleCredential.getAccessToken() == null || googleCredential.getExpirationTimeMilliseconds() <= System.currentTimeMillis()) {
try {
System.out.println("Access token is null so refreshing token");
googleCredential.refreshToken();
} catch (IOException e) {
System.err.println("Error refreshing token for " + googleCredential.getServiceAccountUser());
throw new ClientException(e);
}
}
return googleCredential.getAccessToken();
}
private static Map<String, AbstractGoogleJsonClient> SERVICES_SINGLETONS = Maps.newHashMap();
private static AbstractGoogleJsonClient getService_Singleton(String email, Class classOf) {
String key = email + classOf.getName().toLowerCase();
AbstractGoogleJsonClient clients = SERVICES_SINGLETONS.get(key);
if (clients == null) {
clients = getService(email, classOf);
SERVICES_SINGLETONS.put(key, clients);
}
return clients;
}
private static AbstractGoogleJsonClient getService(String email, Class classOf) {
Collection<String> sets = null;
String classSimpleName = classOf.getSimpleName();
java.util.Set<String> set = new java.util.HashSet<String>();
set.add(DriveScopes.DRIVE);
set.add(GmailScopes.GMAIL_COMPOSE);
sets = java.util.Collections.unmodifiableSet(set);
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
final GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(emailAddress)
.setServiceAccountScopes(sets)
.setServiceAccountUser(email)
.setServiceAccountPrivateKey(privateKey)
.build();
try {
return ((AbstractGoogleJsonClient.Builder) getInnerClass(classOf, "Builder").getConstructors()[0].newInstance(httpTransport, jsonFactory, null))
.setApplicationName("Super Share")
.setHttpRequestInitializer(new Intializer(credential))
.build();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public static Class getInnerClass(Class classOf, String className) {
for (Class inner : classOf.getDeclaredClasses()) {
if (inner.getName().toLowerCase().endsWith(className.toLowerCase())) ;
return inner;
}
return null;
}
public static class Intializer implements HttpRequestInitializer {
public GoogleCredential credential;
public Intializer(GoogleCredential credential) {
this.credential = credential;
}
@Override
public void initialize(HttpRequest httpRequest) throws IOException {
credential.initialize(httpRequest);
httpRequest.setConnectTimeout(3 * 60000);
httpRequest.setReadTimeout(3 * 60000);
}
}
public static class ClientException extends RuntimeException {
public Exception e;
public ClientException(Exception e) {
this.e = e;
}
}
}